﻿using System.Collections.Generic;

namespace ChengNet.StrongCaml.Node
{
    /// <summary>
    /// An extra namespace depth to hide all the classes representing CAML nodes because they're not be instantiated directly.
    /// </summary>
    internal class NamespaceDoc { }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class Query : CamlNode
    {
        internal Query(Where where, OrderBy orderBy = null, GroupBy groupBy = null) : base(where, orderBy, groupBy) { }
        //public Query(Literal literal) : base(literal) { }
    }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class Where : CamlNode
    {
        internal Where(Condition condition) : base(condition) { }
        //public Where(Literal literal) : base(literal) { }
    }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class OrderBy : CamlNode
    {
        internal OrderBy(params FieldRef[] fieldrefs) : base(fieldrefs) { }
        //public OrderBy(params Literal[] literals) : base(literals) { }
    }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    // TODO: attribute "Collapse"
    public class GroupBy : CamlNode
    {
        internal GroupBy(FieldRef fieldref) : base(fieldref) { }
        //public GroupBy(params Literal[] literals) : base(literals) { }
    }

    // TODO: ViewFields - > generalize to different CAML schemas?
    //public class ViewFields : CamlNode
    //{
    //    public ViewFields(params FieldRef[] fieldRefs) : base(fieldRefs) { }
    //    //public ViewFields(params Literal[] literals) : base(literals) { }
    //}

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class UserID : CamlNode { internal UserID() { } }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class Now : CamlNode { internal Now() { } }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class Today : CamlNode
    {
        internal Today(int offset = 0) { if (offset != 0) Attributes = new Dictionary<string, string>() { { "Offset", offset.ToString() } }; }
    }

    /// <summary>Do not instantiate directly. Use <see cref="Caml"/>.</summary>
    public class Literal : CamlNode
    {
        internal Literal(object tag) { serialized = Encode.ScriptEncode((tag ?? string.Empty).ToString()); }
    }
}
